/*
 * AmpelController.cpp
 *
 *  Created on: 14.05.2011
 *      Author: Tim
 */

#include "AmpelController.h"

pthread_mutex_t akt_inst_ampel = PTHREAD_MUTEX_INITIALIZER;	//Mutex fuer das Singleton Pattern
pthread_mutex_t action = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t action_cond;


AmpelController::AmpelController() {
	hal = HAL::getInstance();
	start(NULL);
	ampel_aus();
	ampel_state = AUS;
	pthread_cond_init (&action_cond, NULL);
	blinkAn = 0;

}

AmpelController::~AmpelController() {
	// TODO Auto-generated destructor stub
}

AmpelController* AmpelController::aInstance = 0;

void AmpelController::shutdown(){
	cout << "Shutdown AmpelController" << endl;
}


void AmpelController::execute(void*){

	while(!isStopped()){
		pthread_mutex_lock(&action);
		pthread_cond_wait(&action_cond, &action);
		ampel_state_x = ampel_state;
		switch(ampel_state){
		case GRUEN:
			ampel_gruen();
			break;
		case GELB:
			ampel_gelb();
			break;
		case ROT:
			ampel_rot();
			break;
		case ROT_BLINK:
			ampel_rotBlink();
			break;
		case AUS:
			ampel_aus();
			break;
		case GRUENGELB:
			ampel_gruen_gelb();
			break;
		case ROT_BLINK_SCHNELL:
			ampel_start_schnell();
			break;
		case ROT_BLINK_LANGSAM:
			ampel_start_langsam();
			break;
		case ROT_BLINK_AUS:
			cout << "Ampel sollte ausgehn, kann nicht vorkommen" << endl;
//			timer_stopper();
			break;
		case TIMERPARTY:
			timer_partey();
			break;
		default:
			break;
		}
		pthread_mutex_unlock(&action);

	}

}

void AmpelController::ampel_aufruf(AmpelStates state){

	if(state == ROT_BLINK_AUS){
		timer_stopper();
	}else{
		ampel_state = state;
	}
	pthread_cond_signal(&action_cond);
}

AmpelController* AmpelController::getInstance() {				//Singleton, erster richtiger Versuch
	if ( !aInstance ){
		pthread_mutex_lock(&akt_inst_ampel);
		if ( !aInstance ){
			aInstance = new AmpelController();
		}else{
			cout << "ANMERKUNG: im kritischen Bereich: es ist schon eine Instance vorhanden " << "ThreadID: " << gettid() << endl;
		}
		pthread_mutex_unlock(&akt_inst_ampel);
	}else{
		//cout << "FEHLER: es ist schon eine Instance vorhanden " << "ThreadID: " << gettid() << endl;
	}

	return aInstance;
}//getInstance


void AmpelController::ampel_gruen(){
	hal->HAL_aufruf(AMPELGRUEN, 1);
	hal->HAL_aufruf(AMPELGELB, 0);
	hal->HAL_aufruf(AMPELROT, 0);
}

void AmpelController::ampel_gelb(){
	hal->HAL_aufruf(AMPELGRUEN, 0);
	hal->HAL_aufruf(AMPELGELB, 1);
	hal->HAL_aufruf(AMPELROT, 0);
}

void AmpelController::ampel_rot(){
	hal->HAL_aufruf(AMPELGRUEN, 0);
	hal->HAL_aufruf(AMPELGELB, 0);
	hal->HAL_aufruf(AMPELROT, 1);
}

void AmpelController::ampel_start_schnell(){
	timerSF = new Timer(0,0,1,500000000, AMPEL_ROT_BLINK);		//ampelschnellblinken
	cout << "Ampel blinkt schnell" << endl;
}

void AmpelController::ampel_start_langsam(){
	timerSF = new Timer(0,1,1,0, AMPEL_ROT_BLINK);		//ampelschnellblinken
	cout << "Ampel blinkt langsam" << endl;
}

void AmpelController::timer_stopper(){
	if(timerSF != NULL){
		delete(timerSF);
		timerSF = NULL;
	}
	ampel_aus();
	cout << "Ampel geht aus" << endl;
}

void AmpelController::timer_partey(){
	timerSF = new Timer(0,0,1,50000000, PARTY);		//ampelschnellblinken
}


void AmpelController::ampel_rotBlink(){
	if(!blinkAn){
		hal->HAL_aufruf(AMPELGRUEN, 0);
		hal->HAL_aufruf(AMPELGELB, 0);
		hal->HAL_aufruf(AMPELROT, 1);
		blinkAn = true;
	}else{
		hal->HAL_aufruf(AMPELGRUEN, 0);
		hal->HAL_aufruf(AMPELGELB, 0);
		hal->HAL_aufruf(AMPELROT, 0);
		blinkAn = false;
	}
}


void AmpelController::ampel_aus(){
	hal->HAL_aufruf(AMPELGRUEN, 0);
	hal->HAL_aufruf(AMPELGELB, 0);
	hal->HAL_aufruf(AMPELROT, 0);
}

void AmpelController::ampel_gruen_gelb(){
	hal->HAL_aufruf(AMPELGRUEN, 1);
	hal->HAL_aufruf(AMPELGELB, 1);
	hal->HAL_aufruf(AMPELROT, 0);
}
